package cn.edu.xmu.orderpayment.order.service;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;

import cn.edu.xmu.orderpayment.order.constant.Constants;
import cn.edu.xmu.orderpayment.order.dao.OrderDao;
import cn.edu.xmu.orderpayment.order.microservice.*;
import cn.edu.xmu.orderpayment.order.microservice.vo.*;
import cn.edu.xmu.orderpayment.order.model.bo.Order;
import cn.edu.xmu.orderpayment.order.model.bo.OrderItem;
import cn.edu.xmu.orderpayment.order.model.po.OrderItemPo;
import cn.edu.xmu.orderpayment.order.model.po.OrderPo;
import cn.edu.xmu.orderpayment.order.model.vo.*;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static cn.edu.xmu.oomall.core.util.Common.getListRetVo;
import static cn.edu.xmu.oomall.core.util.ReturnNo.*;
import static cn.edu.xmu.privilegegateway.annotation.util.Common.*;

/**
 *
 * @author Chencheng Liao 22920192204238
 * @Date 2021/12/16
 */
@Service
public class ShopOrderService {
    @Autowired
    private OrderDao orderDao;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private FreightService freightService;

    @Autowired
    private CustomerService customerService;

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<Order> getOrderByOrderId(Long OrderId) {
        return orderDao.getOrderById(OrderId);
    }

    /**
     * 店家查询商户所有订单 (概要)
     * @param shopId
     * @param customerId
     * @param orderSn
     * @param beginTime
     * @param endTime
     * @param page
     * @param pageSize
     * @return ReturnObject
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/16
     */
    @Transactional
    public ReturnObject shopsShopIdOrdersGet(Long shopId, Long customerId, String orderSn, ZonedDateTime beginTime, ZonedDateTime endTime, Integer page, Integer pageSize) {
        return orderDao.shopsShopIdOrdersGet(shopId, customerId, orderSn, beginTime, endTime, page, pageSize);
    }

    /**
     * 店家查询商户所有订单 (概要)
     * @return ReturnObject
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/16
     */
    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public ReturnObject getShopOrderDetail(Long shopId, Long id) {

        ReturnObject returnObject = orderDao.getOrder(id);
        Order order = (Order) returnObject.getData();
        if (order == null) {
            return returnObject;
        }

        if (!order.getShopId().equals(shopId)) {
            return new ReturnObject(RESOURCE_ID_OUTSCOPE, "该订单不属于此商户");
        }

        InternalReturnObject customerRetObj = customerService.getCustomerById(order.getCustomerId());
        SimpleCustomerRetVo simpleCustomerRetVo = (SimpleCustomerRetVo) customerRetObj.getData();
        if (simpleCustomerRetVo == null) {
            return new ReturnObject(RESOURCE_ID_NOTEXIST, "该订单对应用户不存在");
        }

        InternalReturnObject shopRetObj = shopService.getShopById(order.getShopId());
        ShopSimpleRetVo shopRetVo = (ShopSimpleRetVo) shopRetObj.getData();
        if (shopRetVo == null) {
            return new ReturnObject(RESOURCE_ID_NOTEXIST, "该商户不存在");
        }

        ReturnObject orderItemsRetObj = orderDao.getOrderItemsByOrderId(id);
        if (orderItemsRetObj.getData() == null) {
            return new ReturnObject(RESOURCE_ID_NOTEXIST, "订单明细不存在");
        }
        List<SimpleOrderItemRetVo> list = (List<SimpleOrderItemRetVo>) getListRetVo(orderItemsRetObj, SimpleOrderItemRetVo.class).getData();

        OrderInfoRetVo orderInfoRetVo = cloneVo(order, OrderInfoRetVo.class);
        orderInfoRetVo.setCustomer(simpleCustomerRetVo);
        orderInfoRetVo.setShop(shopRetVo);
        orderInfoRetVo.setOrderItem(list);

        return new ReturnObject(orderInfoRetVo);
    }

    /**
     * 店家修改订单（留言）
     * @param shopId 店铺id
     * @param id 订单id
     * @param vo 订单修改视图
     * @return ReturnObject
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/16
     */
    @Transactional
    public ReturnObject shopModifyUserOrder(Long loginId, Long shopId, Long id,String loginName, OrderMessageVo vo) {
        //查看有没有商铺
        InternalReturnObject ret = shopService.getShopById(shopId);
        if (ret.getData() == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST, "店铺不存在");
        }
        //查看有没有订单，是不是这个店铺的
        ReturnObject retOrder = orderDao.getOrder(id);
        if (retOrder.getData() == null) {
            return retOrder;
        }
        Order order = (Order) retOrder.getData();
        if (!order.getShopId().equals(shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE, "不能修改其他店铺订单");
        }
        String message=vo.getMessage();
        order.setMessage(message);
        ReturnObject res = orderDao.updateOrder(order, loginId, loginName);
        return res;
    }

    /**
     * 取消本店铺订单
     * @param shopId 店铺id
     * @param id 订单id
     * @return ReturnObject
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/17
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject cancelOrder(Long shopId, Long id, Long userId, String userName) {
        ReturnObject ret1 = orderDao.getOrder(id);
        if (ret1.getData() == null) {
            return ret1;
        }
        Order order = (Order) ret1.getData();
        if (shopId != 0L && !Objects.equals(order.getShopId(), shopId)) {
            return new ReturnObject(RESOURCE_ID_OUTSCOPE, "本订单不属于该商铺");
        }
        return internalCancelOrder(userId, userName, order);
    }

    private ReturnObject internalCancelOrder(Long userId, String userName, Order order) {

        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        Constants.servletRequestAttributes = servletRequestAttributes;

        List<Order> subOrders = new ArrayList();
        List<OrderItem> orderItemList = new ArrayList<>();
        if (order.getPid() != 0) {
            ReturnObject ret2 = orderDao.getOrder(order.getPid());
            if (ret2.getData() == null) {
                return ret2;
            }
            order = cloneVo(ret2.getData(), Order.class);
            ReturnObject ret3 = orderDao.getOrderByPid(order.getId());
            List<OrderPo> orderPos = (List<OrderPo>) ret3.getData();
            for (OrderPo orderPo : orderPos) {
                Order subOrder = cloneVo(orderPo, Order.class);
                subOrders.add(subOrder);
            }
        }
        // 已完成不能取消
        if (order.getState() == Order.State.COMPLETED.getCode()) {
            return new ReturnObject(RESOURCE_ID_OUTSCOPE, "当前状态禁止此操作");
        }
        // 新订单不退款
        if (order.getState() == Order.State.NEW_ORDER.getCode() || order.getState() == Order.State.PENDING_FINAL_PAYMENT.getCode()) {
            order.setState(Order.State.CANCELED.getCode());
            orderDao.updateOrder(order, userId, userName);
            return new ReturnObject<>();
        }

        if (subOrders.size() == 0) {
            ReturnObject<List> orderItemListRet = orderDao.getOrderItemsByOrderId(order.getId());
            orderItemList = orderItemListRet.getData();
        } else {
            for (Order subOrder : subOrders) {
                ReturnObject<List> orderItemListRet = orderDao.getOrderItemsByOrderId(subOrder.getId());
                List<OrderItemPo> tempList = orderItemListRet.getData();
                for (OrderItemPo orderItem : tempList) {
                    orderItemList.add(cloneVo(orderItem, OrderItem.class));
                }
            }
        }

        // 预售退两笔
        if (order.getAdvancesaleId() != null && order.getAdvancesaleId() != 0) {
            InternalReturnObject<AdvanceSaleRetVo> actVoRet = activityService.getAdvanceActById(order.getAdvancesaleId());
            if (actVoRet.getData() != null) {

                AdvanceSaleRetVo act = actVoRet.getData();
                Long restAmount = order.getOriginPrice() - order.getExpressFee();
                String sn = order.getOrderSn();
                paymentService.refundAll(sn + "-D", (byte) 0, "取消订单退定金");
                paymentService.refund(sn + "-W", restAmount, (byte) 0, "取消订单退尾款");

                order.setState(Order.State.WAIT_REFUND.getCode());
                orderDao.updateOrder(order, userId, userName);
                return new ReturnObject<>();
            }
            return new ReturnObject<>(RESOURCE_ID_NOTEXIST, "该预售活动不存在");
        }
        // 普通退全款
        Long finalAmount = order.getOriginPrice() - order.getPoint() - order.getDiscountPrice() + order.getExpressFee();
        String sn = order.getOrderSn();

        paymentService.refund(order.getOrderSn(), finalAmount, (byte) 0, "取消订单退全款");
        order.setState(Order.State.WAIT_REFUND.getCode());
        orderDao.updateOrder(order, userId, userName);
        if (subOrders.size() != 0) {
            for (Order subOrder : subOrders) {
                subOrder.setState(Order.State.WAIT_REFUND.getCode());
                orderDao.updateOrder(subOrder, userId, userName);
            }
        }
        return new ReturnObject<>();
    }

//    @Transactional
//    public ReturnObject shopsShopIdOrdersIdDelete(Long shopId, Long id) {
//        return orderDao.shopsShopIdOrdersIdDelete(shopId,id);
//    }

    /**
     * 确认团购订单
     *
     * @param
     * @return Object
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/23
     */
    /**
     * 需要登录，传入商店id和订单id
     * 需根据团购规则退款
     */
//    @Transactional(rollbackFor = Exception.class)
//    public ReturnObject confirmGroupOnOrder(Long userId, String userName, Long shopId, Long orderId) {
//
//        ReturnObject orderInDatebase = orderDao.getOrder(orderId);
//        if (orderInDatebase.getData() == null) {
//            //返回数据库的错误
//            return orderInDatebase;
//        }
//
//        Order order = (Order) orderInDatebase.getData();
//        if (!order.getCustomerId().equals(userId) //用户对不上
//                || !order.getShopId().equals(shopId)  //shopId对不上
//                || order.getGrouponId() == null   //不是团购
//        ) {
//            return new ReturnObject(ReturnNo.STATENOTALLOW);  //TODO 不知道返回什么
//        }
//        InternalReturnObject<GrouponActRetVo> activityReturnObject = activityService.getGrouponActById(order.getGrouponId());
//        if (activityReturnObject.getData() == null) {
//            return new ReturnObject(RESOURCE_ID_NOTEXIST);
//        }
//        GrouponActRetVo grouponActRetVo = activityReturnObject.getData();
//        //判断是不是上线的团购活动
//        if (grouponActRetVo.getState() != ActState.ONLINE) {
//            return new ReturnObject(ReturnNo.STATENOTALLOW, "此团购活动不是上线状态");
//        }
//        List<GroupOnStrategyRetVo> strategyList = grouponActRetVo.getStrategy();
//
//        ReturnObject returnObject = orderDao.getOrderByGrouponActivityId(grouponActRetVo.getId());
//        if (returnObject.getData() == null) {
//            return returnObject;   //
//        }
//        List<OrderPo> orderPoList = (List<OrderPo>) returnObject.getData();
//
//        int count = orderPoList.size();
//        int strategyCount = orderPoList.size();
//        int percentage = 1000;
//        for (GroupOnStrategyRetVo groupOnStrategyRetVo : strategyList) {
//            if (count >= groupOnStrategyRetVo.getQuantity()) {
//                percentage = groupOnStrategyRetVo.getPercentage();
//            }
//        }
//        Long refundAmount = order.getOriginPrice();
//        if (percentage != 1000) {
//            refundAmount = order.getOriginPrice() - order.getOriginPrice() * percentage / 1000;
//        }
//
//        paymentService.refund(order.getOrderSn(), refundAmount, (byte) 0, "团购确认根据规则退款");
//
//
//        order.setState(Order.State.PAYMENT_COMPLETED.getCode());
//
//        return orderDao.updateOrder(order, userId, userName);
//    }

    /**
     * 店家对订单标记发货
     *
     * @param
     * @return Object
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/12
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject deliver(Long loginUserId, Long shopId, Long id, String freightSn, String loginName) {
        //查看有没有商铺
        InternalReturnObject<ShopSimpleRetVo> retShop = shopService.getShopById(shopId);
        if (retShop.getData() == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST, "店铺不存在");
        }
        //查看有没有订单，是不是这个店铺的
        ReturnObject retOrder = orderDao.getOrder(id);
        if (retOrder.getData() == null) return retOrder;
        Order order = (Order) retOrder.getData();
        if (!order.getShopId().equals(shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE, "不能修改其他店铺订单");
        }
        if(!order.getState().equals(Order.State.PENDING_DELIVERY.getCode())){
            return new ReturnObject(STATENOTALLOW,"当前状态禁止此操作");
        }
        order.setState(Order.State.SHIPPED.getCode());
        order.setShipmentSn(freightSn);
        order.setConfirmTime(LocalDateTime.now());
        ReturnObject res = orderDao.updateOrder(order, loginUserId, loginName);
        if(res.getCode()==ReturnNo.INTERNAL_SERVER_ERR)
            return  res;
        return new ReturnObject();
    }

    /**
     * 此类订单是用于售后换货或者是售后支付
     * 如果是售后换货的新建状态是待发货，价格为0"
     * 如果是售后支付则新建状态时待付款
     * 需要传入orderInfo，包括订单信息、商品信息以及是否由顾客支付
     *
     * @return
     * @creator wang xusheng
     */
//    @Transactional(rollbackFor = Exception.class)
//    public ReturnObject createAfterSaleOrder(NewAfterSaleOrderVo newAfterSaleOrderVo, Long loginUserId, String loginName) {
//        SimpleRegionRetVo regionRetVo = freightService.getRegionById(newAfterSaleOrderVo.getRegionId()).getData();
//        if (regionRetVo == null) {
//            return new ReturnObject(RESOURCE_ID_NOTEXIST, "地区不存在");
//        }
//        if (regionRetVo.getState() == 1) {
//            return new ReturnObject(FREIGHT_REGION_NOTREACH, "该地区停发");
//        }
//        if (regionRetVo.getState() == 2) {
//            return new ReturnObject(FREIGHT_REGIONOBSOLETE, "该地区已废弃");
//        }
//
//
//        InternalReturnObject<SimpleCustomerRetVo> simpleCustomerRetVoInternalReturnObject =
//                customerService.getCustomerById(newAfterSaleOrderVo.getCustomerId());
//        if (simpleCustomerRetVoInternalReturnObject.getData() == null)
//            return new ReturnObject(RESOURCE_ID_NOTEXIST, "该顾客不存在");
//
//        List<AfterSaleOrderItemVo> afterSaleOrderItemVoList = newAfterSaleOrderVo.getOrderItems();
//        InternalReturnObject<ShopSimpleRetVo> shopRetVoInternalReturnObject = null;
//
//        Long shopId = null;
//        List<OrderItem> orderItemList = new ArrayList<>();
//        for (AfterSaleOrderItemVo itemVo : afterSaleOrderItemVoList) {
//            OrderItem orderItem = cloneVo(itemVo, OrderItem.class);
//            orderItem.init();
//
//            InternalReturnObject<ProductRetVo> productRet = goodsService.getProductById(itemVo.getProductId());
//            if (productRet.getData() == null) return new ReturnObject(RESOURCE_ID_NOTEXIST, "货品不存在");
//            InternalReturnObject<OnSaleRetVo> onSaleRetVoInternalReturnObject = goodsService.selectFullOnsale(itemVo.getOnsaleId());
//            if (onSaleRetVoInternalReturnObject.getData() == null)
//                return new ReturnObject(RESOURCE_ID_NOTEXIST, "该货品没有销售");
//            ProductRetVo productRetVo = (ProductRetVo) productRet.getData();
//            shopId = productRetVo.getShop().getId();
//            shopRetVoInternalReturnObject = shopService.getShopById(shopId);
//            if (shopRetVoInternalReturnObject.getData() == null) return new ReturnObject(RESOURCE_ID_NOTEXIST, "店铺不存在");
//            orderItem.setShopId(shopId);
//            orderItem.setName(productRetVo.getName());
//            setPoCreatedFields(orderItem, loginUserId, loginName);
//            orderItemList.add(orderItem);
//        }
//        Order order = cloneVo(newAfterSaleOrderVo, Order.class);
//        order.init();
//        order.setShopId(shopId);
//        setPoCreatedFields(order, loginUserId, loginName);
//
//        ReturnObject<OrderPo> ret = orderDao.createOrder(order);
//        List<SimpleOrderItemRetVo> simpleOrderItemRetVoList = new ArrayList<>();
//        for (OrderItem item : orderItemList) {
//            item.setOrderId(ret.getData().getId());
//            ReturnObject<OrderItemPo> poRet = orderDao.createOrderItem(item);
//            SimpleOrderItemRetVo simpleOrderItemRetVo = cloneVo(poRet.getData(), SimpleOrderItemRetVo.class);
//            simpleOrderItemRetVoList.add(simpleOrderItemRetVo);
//        }
//
//        OrderInfoRetVo orderInfoRetVo = cloneVo(ret.getData(), OrderInfoRetVo.class);
//        orderInfoRetVo.setOrderItem(simpleOrderItemRetVoList);
//
//        orderInfoRetVo.setCustomer(simpleCustomerRetVoInternalReturnObject.getData());
//        orderInfoRetVo.setShop(shopRetVoInternalReturnObject.getData());
//
//        return new ReturnObject<>(orderInfoRetVo);
//    }

    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public ReturnObject getOrderItemById(Long id) {
        ReturnObject<OrderItem> orderItemReturnObject = orderDao.getOrderItemById(id);
        if (orderItemReturnObject.getData() == null) return orderItemReturnObject;
        return new ReturnObject(cloneVo(orderItemReturnObject.getData(), OrderItemRetVo.class));
    }

    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public ReturnObject getOrderDetailByOrderSn(String orderSn) {
        ReturnObject orderPoRet = orderDao.getOrderByOrderSn(orderSn);
        if (orderPoRet.getCode() != OK)
            return orderPoRet;
        OrderPo orderPo = (OrderPo) orderPoRet.getData();

        ReturnObject orderItemsRet = orderDao.getOrderItemsByOrderId(orderPo.getId());
        if (orderItemsRet.getCode() != OK)
            return orderItemsRet;
        List<OrderItemPo> pos = (List<OrderItemPo>) orderItemsRet.getData();
        ReturnObject listRet = getListRetVo(new ReturnObject<>(pos), OrderItemRetVo.class);
        List<OrderItemRetVo> retVos = (List<OrderItemRetVo>) listRet.getData();

        SimpleOrderRetVo simpleOrderRetVo = cloneVo(orderPo, SimpleOrderRetVo.class);
        simpleOrderRetVo.setOrderItems(retVos);
        return new ReturnObject<>(simpleOrderRetVo);
    }


}
